package com.hthy.futures.api;

import com.hthy.futures.AppContext;
import com.hthy.futures.bean.DeclareMoney;
import com.hthy.futures.bean.TradeOderStr;
import com.hthy.futures.bean.Vhead;
import com.hthy.futures.utils.StringUtils;

import net.hthy.bean.Trade;

import java.text.DecimalFormat;

/**
 * smartTrade 交易api
 * Author:  Mr.bingley
 * Version:
 * Date:  2017/3/17
 * <p>
 * <p>
 * 2013 查询历史单据请求 是那個字段吗？
 * /**
 * 2069 出入金申请  (2070 出入金申请应答)  pb文件没有
 * double db_order_size = 19;             // 这个是手数吗？TODO
 * <p>
 * 2013 查询历史单据请求 是那個字段吗？
 * /**
 * 2069 出入金申请  (2070 出入金申请应答)  pb文件没有
 * double db_order_size = 19;             // 这个是手数吗？TODO
 * <p>
 * 2013 查询历史单据请求 是那個字段吗？
 * /**
 * 2069 出入金申请  (2070 出入金申请应答)  pb文件没有
 * double db_order_size = 19;             // 这个是手数吗？TODO
 */

/**
 * 2013 查询历史单据请求 是那個字段吗？
 *  /**
 * 2069 出入金申请  (2070 出入金申请应答)  pb文件没有
 * 	double db_order_size = 19;             // 这个是手数吗？TODO
 */

/** how to use?
 *

 // 发送命令
 byte[] baseStr2 = ST_QuoteApi.checkLogin();
 quoteSocketClinet.sendData(baseStr2);

 // 传参数
 Quote.ProductPriceInfo productPriceInfo = Quote.ProductPriceInfo.newBuilder().setSsProductCode(productCode).build();
 Quote.GetHistoryKDataRequest getHistoryKDataRequest = Quote.GetHistoryKDataRequest.newBuilder().setUiKDataType(dataType).setUiKDataIndex(dataIndex).setUiKDataNumber(K_REQUEST_NUM).setProductPriceInfo(productPriceInfo).build();
 byte[] bytes2 = getHistoryKDataRequest.toByteArray();
 int serializedSize = getHistoryKDataRequest.getSerializedSize();
 return getBaseStr("0600",bytes2,serializedSize);

 // 解析
 try {
     byte[] data = responsePacket.getData(); // 获取接收的byte数组，不为null
     byte[] bytes = StringUtils.subBytes(data, 37, data.length - 37);
     Trade.LoginResponseMsg loginResponseMsg = Trade.LoginResponseMsg.parseFrom(bytes);
     AppContext.accountId = loginResponseMsg.getUiUserUid()+"";
     AppContext.sessionId = loginResponseMsg.getSsLoginSession();
     AppContext.accountName = loginResponseMsg.getSsUserName();
     } catch (Exception e) {
     e.printStackTrace();
 }
 */

public class ST_TradeApi {
    /**
     * 登陆
     *
     * @param
     * @return
     */
    public static byte[] login(String account, String pwd) {
        /*Map<String, String> map = new HashMap<>();      // 20210201  1    10110011  101101234

        map.put("1", account);  // accountid
        map.put("91", pwd); // 用户密码----明文     资金密码也是一样的
        *//*map.put("433","1");  // 客户系统版本
        map.put("434","");  // 客户交易协议版本
        map.put("435","");  // cfca验证
        map.put("436","");  // 接入类型—pc或手机*/

        Trade.LoginRequestMsg loginRequestMsg = Trade.LoginRequestMsg.newBuilder()
                .setSsUsername(account)
                .setSsPassword(pwd).build();
        byte[] bytes2 = loginRequestMsg.toByteArray();
        int serializedSize = loginRequestMsg.getSerializedSize();
        return getBaseStr("1001", bytes2, serializedSize);
    }

    /**
     * 1003 修改密码
     *
     * @return
     */
    public static byte[] updatePwd(int pwdType, String newPwd, String oldPwd) {
        /*Map<String, String> map = new HashMap<>();
        map.put("336", AppContext.sessionId);  // 会话sessionid
        map.put("8131", pwdType);  //  密码类型：‘0’: 主密码(交易密码）‘1’: 只读密码‘2’: 电话密码‘3’: 资金密码
        map.put("9107", newPwd);  // 新密码
        map.put("91", oldPwd);  // 旧密码*/

        Trade.ChangePasswordRequestMsg.ChangePasswordType changePasswordType = Trade.ChangePasswordRequestMsg.ChangePasswordType.valueOf(pwdType);

        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();

        Trade.ChangePasswordRequestMsg changePasswordRequestMsg = Trade.ChangePasswordRequestMsg.newBuilder()
                .setCommonRequest(requestCommonMsg)
                .setSsCurrPassword(oldPwd)
                .setSsNewPassword(newPwd)
                .setUiPasswordType(changePasswordType)
                .build();
        byte[] bytes2 = changePasswordRequestMsg.toByteArray();
        int serializedSize = changePasswordRequestMsg.getSerializedSize();
        return getBaseStr("1003", bytes2, serializedSize);
    }


    /**
     * 交易命令 (属于新订单）
     *
     * @return
     */
    public static byte[] trade(boolean isMarkOrder, String orderCode, TradeOderStr tradeOderStr) {
        // 拼接头部后的json字符串
       /* Map<String, String> map = new HashMap<>();
        map.put("1", AppContext.accountId+"");
        map.put("336", AppContext.sessionId);
        map.put("5", tradeOderStr.tradeFlag);  // 下单标志‘1’-  新建单‘2’ - 修改限价单‘3’ -（修改止损，获利价）‘4’ - 撤销单
        map.put("77", tradeOderStr.tradeOC);  // 开仓平仓 ？？1’ - 建仓‘2’ - 平仓
        map.put("37", tradeOderStr.tradeNum);  // 单号
        map.put("55", tradeOderStr.tradeCode);  // 商品代码
        map.put("38", tradeOderStr.tradeBuyCount);  // 手数， TODO

        map.put("40", tradeOderStr.trade_data_type);  // 代表市价单   单据类型‘1’ - 市价单 ’2’ - 限价单
        // map.put("8026", "456");  // 允许偏离点差
        // map.put("8029", "1");  // 归档

        //  map.put("432", "1");  // 截至日期

        //  map.put("58", "busicess"); // 备注
        // map.put("8032", "1");  // 反手建仓
        map.put("8031", tradeOderStr.trade_operation_type);  // 操作类型1帐户2代客下单3系统斩仓4结算锁仓斩仓
        map.put("54", tradeOderStr.trade_direction); // 买卖方向    s代表卖 b买

        if (!StringUtils.isEmpty(tradeOderStr.trade_dicount_price)) {
            map.put("99", tradeOderStr.trade_dicount_price);  // 止盈价
        }
        if (!StringUtils.isEmpty(tradeOderStr.trade_stop_price)) {
            map.put("8025", tradeOderStr.trade_stop_price);  // 止损价
        }
        if (isMarkOrder) {
            map.put("8028", tradeOderStr.trade_type);  // 交易类型   ‘1’- buy ,‘2’ - sell ,‘3’ - buy limit ,‘4’ - buy stop ,‘5’ - sell limit ,‘6’ - sell stop
        } else {
            map.put("44", tradeOderStr.trade_commision_price);  // 委托价格
            // map.put("8027","123")  // 客户端报价
            map.put("8030", "3"); // 效力类型
            map.put("8028", tradeOderStr.trade_type);  // 交易类型   ‘1’- buy ,‘2’ - sell ,‘3’ - buy limit ,‘4’ - buy stop ,‘5’ - sell limit ,‘6’ - sell stop
        }*/

        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();
        Trade.TradeFlag tradeFlag = Trade.TradeFlag.valueOf(Integer.parseInt(tradeOderStr.tradeFlag));
        Trade.OperationOpenClose operationOpenClose = Trade.OperationOpenClose.valueOf(Integer.parseInt(tradeOderStr.tradeOC));
        Trade.OrderType orderType = Trade.OrderType.valueOf(Integer.parseInt(tradeOderStr.trade_data_type));
        Trade.LimitOrderType limitOrderType = Trade.LimitOrderType.valueOf(Integer.parseInt(tradeOderStr.trade_type));
        // Trade.ValidType.valueOf("3");  ----这个应该填什么合适
        Trade.OrderDirection orderDirection = Trade.OrderDirection.valueOf(tradeOderStr.trade_direction == "b" ? 1 : 2);
        Trade.OperationType operationType = Trade.OperationType.valueOf(Integer.parseInt(tradeOderStr.trade_operation_type));

        Trade.MakeOrderRequestMsg makeOrderRequestMsg = Trade.MakeOrderRequestMsg.newBuilder()
                .setCommonRequest(requestCommonMsg)
                .setUiUserUid(AppContext.accountId)
                .setTradeFlag(tradeFlag)
                .setUiMaxDeviationPips(-1)
                .setValidType(Trade.ValidType.valueOf(isMarkOrder == true ? 3 : 2))   // 挂单中设置2 市价单为3
                .setOpenClose(operationOpenClose)
                .setUiOrderUid(StringUtils.toInt(tradeOderStr.tradeNum, 0))
                .setSsProductCode(tradeOderStr.tradeCode)
                .setDbOrderSize(StringUtils.toDouble(tradeOderStr.tradeBuyCount))
                .setOrderType(orderType)
                .setDbOrderPrice(StringUtils.toDouble(tradeOderStr.trade_commision_price))
                .setDbSlPrice(StringUtils.toDouble(tradeOderStr.trade_stop_price))
                .setDbTpPrice(StringUtils.toDouble(tradeOderStr.trade_dicount_price))
                .setLimitOrderType(limitOrderType)
                .setOrderDirection(orderDirection)
                .setOperationType(operationType)
                .build();

        byte[] bytes2 = makeOrderRequestMsg.toByteArray();
        int serializedSize = makeOrderRequestMsg.getSerializedSize();
        return getBaseStr("1011", bytes2, serializedSize);
    }


    /**
     * 2015 查询交易商品 / 2051 查询公告抬头请求 /2003 查询资金请求/2005 查询单据请求
     * 2007 查询当前资金流水请求 /2019 查询出入金请求(2020 查询出入金应答)
     * 2011 查询历史资金流水请求
     *
     * @return
     */
    public static byte[] searchGoods(String searchCode) {
        /*Map<String, String> map = new HashMap<>();
        map.put("1", AppContext.accountId);  // TODO
        map.put("336", AppContext.sessionId);
        return getBaseStr(map, searchCode);*/


        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();
        Trade.QueryCurrentDataRequestMsg queryCurrentDataRequestMsg = Trade.QueryCurrentDataRequestMsg.newBuilder()
                .setUiUserUid(AppContext.accountId)
                .setCommonRequest(requestCommonMsg)
                .build();
        byte[] bytes2 = queryCurrentDataRequestMsg.toByteArray();
        int serializedSize = queryCurrentDataRequestMsg.getSerializedSize();
        return getBaseStr(searchCode, bytes2, serializedSize);


    }


    /**
     * 2053 查询公告内容
     *
     * @param noticeId
     * @return
     */
    public static byte[] searchNoticeContent(String noticeId) {
     /*   Map<String, String> map = new HashMap<>();
        map.put("8110", noticeId);  // TODO
        // map.put("1", AppContext.accountId);  // TODO
        map.put("336", AppContext.sessionId);*/
        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();

        Trade.QueryNoticeContentRequestMsg noticeContentRequestMsg = Trade.QueryNoticeContentRequestMsg.newBuilder()
                .setCommonRequest(requestCommonMsg)
                .setUiNoticeUid(StringUtils.toInt(noticeId, 0))
                .build();

        byte[] bytes2 = noticeContentRequestMsg.toByteArray();
        int serializedSize = noticeContentRequestMsg.getSerializedSize();
        return getBaseStr("2053", bytes2, serializedSize);
    }


    /**
     * 2013 查询历史单据请求
     *
     * @return
     */
    public static byte[] seachHistoryData(String orderCode, String startTime, String endTime) {
        // 拼接头部后的json字符串
        /*Map<String, String> map = new HashMap<>();
        map.put("1", AppContext.account);                // ---- TODO????
        map.put("336", AppContext.sessionId);
        map.put("8033", startTime);  // 起始日期
        map.put("8034", endTime);  //  结束日期 */

        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();
        Trade.QueryHistoricalDataRequestMsg historicalDataRequestMsg = Trade.QueryHistoricalDataRequestMsg.newBuilder()
                .setCommonRequest(requestCommonMsg)
                .setSsUserName(AppContext.account)
                .setSsStartDate(startTime)
                .setSsEndDate(endTime)
                .build();

        byte[] bytes2 = historicalDataRequestMsg.toByteArray();
        int serializedSize = historicalDataRequestMsg.getSerializedSize();
        return getBaseStr("2013", bytes2, serializedSize);
    }


    /**
     * 2017 出入金申请  (2018 出入金申请应答)
     *
     * @return
     */
    public static byte[] moneyDeclaretrade(DeclareMoney declareMoney) {
     /*   // 拼接头部后的json字符串
        Map<String, String> map = new HashMap<>();
        map.put("1", AppContext.accountId+"");
        map.put("336", AppContext.sessionId);
        //'1', 入金 '2', 出金 '3', 红冲 '4', 蓝补 '5', 签约 '6', 解约 '7', 调账入金 '8', 调账出金 '9'  交易所手续费结转
        map.put("9310", declareMoney.de_operType);  // 操作类型  TODO
        map.put("9311", declareMoney.de_out_in_money);  // 出入金金额 TODO
        // map.put("8107", "13537688026");  // 电话 TODO
        //map.put("9305", "中国银行");  // 开户行名称 TODO
        //map.put("9309", "11231231");  // 银行卡号 TODO
        // map.put("8108", "123");  // TODO  证件号码
        // map.put("8025", declareMoney.de_stop_money);  // TODO  止损价
        //  map.put("8056", declareMoney.de_userId);  // 申请人id TODO
        map.put("9415", declareMoney.de_fundPwd);  // 资金密码  TODO
        // orderNum 代表头部的命令*/


        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();
        Trade.TransRequestMsg transRequestMsg = Trade.TransRequestMsg.newBuilder()
                .setCommonRequest(requestCommonMsg)
                .setUiUserUid(AppContext.accountId)
                .setUiTransType(declareMoney.de_operType)
                .setDbTransAmount(StringUtils.toDouble(declareMoney.de_out_in_money))
                .setSsTransPassword(declareMoney.de_fundPwd)
                .build();
        byte[] bytes2 = transRequestMsg.toByteArray();
        int serializedSize = transRequestMsg.getSerializedSize();
        return getBaseStr("2017", bytes2, serializedSize);
    }

    /**
     * 2069 入金申请  (2070 入金申请应答)
     *
     * @return
     */
    public static byte[] moneyPushPullDeclaretrade(DeclareMoney declareMoney) {
        // 拼接头部后的json字符串
       /* Map<String, String> map = new HashMap<>();
        map.put("1", AppContext.accountId + "");
        map.put("336", AppContext.sessionId);
        //'1', 入金 '2', 出金 '3', 红冲 '4', 蓝补 '5', 签约 '6', 解约 '7', 调账入金 '8', 调账出金 '9'  交易所手续费结转
        map.put("9310", declareMoney.de_operType+"");  // 操作类型  TODO
        map.put("9311", declareMoney.de_out_in_money);  // 出入金金额 TODO
        // map.put("8107", "13537688026");  // 电话 TODO
        //map.put("9305", "中国银行");  // 开户行名称 TODO
        //map.put("9309", "11231231");  // 银行卡号 TODO
        // map.put("8025", declareMoney.de_stop_money);  // TODO  止损价
        map.put("8056", AppContext.accountId + "");  // 申请人id TODO
        map.put("9415", declareMoney.de_fundPwd);  // 资金密码  TODO
        map.put("8108", declareMoney.de_licence_number);  // TODO  证件号码
        map.put("9000", declareMoney.de_other_paramters);*/
        // orderNum 代表头部的命令

        Trade.RequestCommonMsg requestCommonMsg = Trade.RequestCommonMsg.newBuilder().setSsLoginSession(AppContext.sessionId).build();
        Trade.CallbackPayRequestMsg callbackPayRequestMsg = Trade.CallbackPayRequestMsg.newBuilder()
                .setCommonRequest(requestCommonMsg)
                .setUiUserUid(AppContext.accountId)
                .setUiTransType(declareMoney.de_operType)
                .setDbTransAmount(StringUtils.toDouble(declareMoney.de_out_in_money))
                .setSsTransPassword(declareMoney.de_fundPwd)
                .build();

        byte[] bytes2 = callbackPayRequestMsg.toByteArray();
        int serializedSize = callbackPayRequestMsg.getSerializedSize();
        return getBaseStr("2069", bytes2, serializedSize);
    }


    /**
     * 只得到报文头
     *
     * @param code
     * @return
     */
    public static byte[] getBaseHead(String code) {
        //把二进制转化为十进制
        // 35584
        String codeStr = Integer.valueOf(code, 16).toString();

        String str1 = 37 + "";
        DecimalFormat df = new DecimalFormat("00000000");
        String lenth = df.format(Integer.parseInt(str1));
        String phonecode = df.format(Integer.parseInt(codeStr));   // TODO

        Vhead vhead = new Vhead();
        vhead.lenth = lenth;
        vhead.phone = phonecode;

        byte[] bytes1 = vhead.getHead().getBytes();
        return bytes1;
    }


    /**
     * 报文头+pb文件内容
     *
     * @param bytes
     * @param serializedSize
     * @return
     */
    // 1 把二进制转化为十进制 　Integer.valueOf("1010",2).toString()
    public static byte[] getBaseStr(String codeStr, byte[] bytes, int serializedSize) {
        //把二进制转化为十进制
        // 35584
        //String codeStr  = Integer.valueOf(code, 16).toString();   // 是对应这个吗

        String str1 = serializedSize + 37 + "";
        DecimalFormat df = new DecimalFormat("00000000");
        String lenth = df.format(Integer.parseInt(str1));
        String phonecode = df.format(Integer.parseInt(codeStr));

        Vhead vhead = new Vhead();
        vhead.lenth = lenth;
        vhead.phone = phonecode;

        byte[] bytes1 = vhead.getHead().getBytes();
        return addBytes(bytes1, bytes);
    }

    /**
     * @param data1
     * @param data2
     * @return data1 与 data2拼接的结果
     */
    public static byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;
    }
}
